home *** CD-ROM | disk | FTP | other *** search
- Path: news.ucdavis.edu!quad!knight
- From: knight@quad.cs.ucdavis.edu (James Knight)
- Newsgroups: comp.lang.c,comp.unix.programmer
- Subject: Re: Q: '\n' character
- Followup-To: comp.lang.c,comp.unix.programmer
- Date: 15 Apr 1996 19:36:09 GMT
- Organization: University of California, Davis
- Message-ID: <4ku8f9$d3o@mark.ucdavis.edu>
- References: <4kj66f$k0o@ren.cei.net> <4kmdsv$ojc@masala.cc.uh.edu> <4kmhpsINN7ak@keats.ugrad.cs.ubc.ca> <AD97189A966891F2@mcdiala02.it.luc.edu> <4ktn04INNoev@keats.ugrad.cs.ubc.ca>
- NNTP-Posting-Host: quad.cs.ucdavis.edu
- X-Newsreader: TIN [version 1.2 PL2]
-
- Kazimir Kylheku (c2a192@ugrad.cs.ubc.ca) wrote:
- : In article <AD97189A966891F2@mcdiala02.it.luc.edu>,
- : Verne Arase <VArase@varase.it.luc.edu> wrote:
- : >In article <4kmhpsINN7ak@keats.ugrad.cs.ubc.ca>,
- : >c2a192@ugrad.cs.ubc.ca (Kazimir Kylheku) wrote:
- : >
- : >This is a failing of the C standard I/O library; fgets() _ought_ to have
- : >returned the length read.
-
- : Yes it should. A lot of the standard I/O library is braindead, but it had to be
- : standardized a certain way to reflect existing practice and preserve the
- : correctness of existing programs.
-
- : Or better still: how about returning a pointer to the last character read! This
- : would point to a null character if _no_ characters were read (thus indicating
- : EOF on the attempt to read the first character), or to either a newline or a
- : non-newline if at least one character was read. It would always be valid to
- : dereference the returned pointer, provided a valid buffer was passed in. A use
- : of fgets would then look like:
-
-
- I just bypass all of the problems with fgets using the function below. It handles
- lines of any length, does the elimination of the newline, and the rest of my
- program doesn't have to worry about where to store the line. Admittedly, it won't
- work for the original problem (for which Unix already has several solutions), but
- in the much more common case of reading a single file, or getting user input, this
- function makes the rest of the program much simpler.
-
-
-
- /*
- * my_getline
- *
- * Read a line of any length, store it in an internal buffer, and
- * return the internal buffer (along with a length value if desired).
- *
- * NOTE: Each line read will overwrite the previous line read. So,
- * make a copy of any line you want to keep around.
- *
- * Parameters:
- * fp - A FILE pointer open for reading.
- * len_out - Address to where to store the line length.
- *
- * Returns:
- * An internal buffer containing the line, or NULL on EOF or error.
- */
- char *my_getline(FILE *fp, int *len_out)
- {
- static int bufsize = 0;
- static char *buffer = NULL;
- int size, len, flag;
-
- /*
- * Initialize the internal buffer, if necessary.
- */
- if (buffer == NULL) {
- bufsize = 128;
- if ((buffer = malloc(bufsize)) == NULL)
- return NULL;
- }
-
- /*
- * Read the first part of the line.
- */
- flag = 0;
- buffer[bufsize-2] = '\0';
-
- if (fgets(buffer, bufsize, fp) == NULL)
- return NULL;
- else if (buffer[bufsize-2] == '\0' || buffer[bufsize-2] == '\n') {
- len = strlen(buffer);
- flag = 1;
- }
-
- /*
- * If the line is longer, then realloc the internal buffer and
- * read the next section of the line.
- */
- while (!flag) {
- size = bufsize - 1;
- bufsize += bufsize;
- if ((buffer = realloc(buffer, bufsize)) == NULL)
- return NULL;
-
- buffer[bufsize-2] = '\0';
- if (fgets(buffer + size, bufsize - size, fp) == NULL) {
- len = size;
- flag = 1;
- }
- else if (!buffer[bufsize-2] || buffer[bufsize-2] == '\n') {
- len = size + strlen(buffer + size);
- flag = 1;
- }
- }
-
- /*
- * Strip the newline from the line, if it's there.
- */
- if (buffer[len-1] == '\n')
- buffer[--len] = '\0';
-
- if (len_out) *len_out = len;
- return buffer;
- }
-
-